package q2016_01_1;

/**
 * 
 * @author ZHANGHJ14
 *
 */
public class Question5 {
	public static void main(String[] args) {
		ByteStore store = new ByteStore();
		MyItem item0 = new MyItem((byte) 0, (byte) 0, (byte) 0);
		MyItem item1 = new MyItem((byte) 1, (byte) 1, (byte) 1);
		MyItem item2 = new MyItem((byte) 2, (byte) 2, (byte) 2);

		store.putMyItem(0, item0);
		store.putMyItem(1, item1);
		store.putMyItem(2, item2);

		MyItem newItem0 = store.getMyItem(0);
		MyItem newItem1 = store.getMyItem(1);
		MyItem newItem2 = store.getMyItem(2);

		System.out.println(item0.equals(newItem0));
		System.out.println(item1.equals(newItem1));
		System.out.println(item2.equals(newItem2));

		ByteStore2 byteStore2 = new ByteStore2();
		byteStore2.putMyItem(1, item1);
		MyItem new2Item1 = byteStore2.getMyItem(1);
		System.out.println(item1.equals(new2Item1));

		/*ByteStore store2 = new ByteStore();
		MyItem[] items = generateMyItemInstances(1000);
		for (int i = 0; i < items.length; i++) {
			store2.putMyItem(i, items[i]);
		}
		quickSort(store2, 0, items.length - 1);
		print(store2, 100);*/
	}

	public static void quickSort(ByteStore store, int low, int high) {

		int l = low;
		int h = high;
		MyItem povit = store.getMyItem(low);

		while (l < h) {
			while (l < h && ((Comparable) store.getMyItem(h)).compareTo(povit) < 0)
				h--;
			if (l < h) {
				swap(store, h, l);
				l++;
			}

			while (l < h && ((Comparable) store.getMyItem(l)).compareTo(povit) >= 0)
				l++;

			if (l < h) {
				swap(store, h, l);
				h--;
			}
		}

		if (l > low)
			quickSort(store, low, l - 1);
		if (h < high)
			quickSort(store, l + 1, high);
	}

	public static void swap(ByteStore store, int i, int j) {
		MyItem temp = store.getMyItem(i);
		store.putMyItem(i, store.getMyItem(j));
		store.putMyItem(j, temp);
	}

	public static void quickSort2(int[] arr, int low, int high) {
		int l = low;
		int h = high;
		int povit = arr[low];

		while (l < h) {
			while (l < h && arr[h] >= povit)
				h--;
			if (l < h) {
				int temp = arr[h];
				arr[h] = arr[l];
				arr[l] = temp;
				l++;
			}

			while (l < h && arr[l] <= povit)
				l++;

			if (l < h) {
				int temp = arr[h];
				arr[h] = arr[l];
				arr[l] = temp;
				h--;
			}
		}

		if (l > low)
			quickSort2(arr, low, l - 1);
		if (h < high)
			quickSort2(arr, l + 1, high);
	}

	public static int[] generateInts(int num) {
		int[] array = new int[num];
		for (int i = 0; i < num; i++) {
			array[i] = (int) (Math.random() * 256);
		}
		return array;
	}

	public static MyItem generateMyItemInstance() {
		MyItem myItem = new MyItem();
		myItem.setType((byte) (Math.random() * 256));
		myItem.setPrice((byte) (Math.random() * 256));
		myItem.setColor((byte) (Math.random() * 256));
		return myItem;
	}

	public static MyItem[] generateMyItemInstances(int num) {
		MyItem[] array = new MyItem[num];
		for (int i = 0; i < num; i++) {
			array[i] = generateMyItemInstance();
		}
		return array;
	}

	public static void print(ByteStore store, int num) {
		for (int i = 0; i < num; i++) {
			System.out.println(store.getMyItem(i));
		}
	}
}

class MyItem implements Comparable<MyItem> {
	private byte type;
	private byte color;
	private byte price;

	public MyItem() {
		super();
	}

	public MyItem(byte type, byte color, byte price) {
		super();
		this.type = type;
		this.color = color;
		this.price = price;
	}

	public byte getType() {
		return type;
	}

	public void setType(byte type) {
		this.type = type;
	}

	public byte getColor() {
		return color;
	}

	public void setColor(byte color) {
		this.color = color;
	}

	public byte getPrice() {
		return price;
	}

	public void setPrice(byte price) {
		this.price = price;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof MyItem) {
			MyItem item = (MyItem) obj;
			if (this.color == item.getColor() 
					&& this.price == item.getPrice() 
					&& this.type == item.getType()) {
				return true;
			} else {
				return false;
			}
		} else {
			return false;
		}
	}

	@Override
	public int compareTo(MyItem item) {
		if (this.getPrice() == item.getPrice()) {
			return 0;
		} else if (this.getPrice() > item.getPrice()) {
			return 1;
		} else {
			return -1;
		}
	}

	@Override
	public String toString() {
		return "MyItem [type=" + type + ", color=" + color + ", price=" + price + "]";
	}
}

class ByteStore {
	private static final int SIZE = 1000 * 3;
	private static final int TYPE_OFFSET = 0;
	private static final int COLOR_OFFSET = 1;
	private static final int PRICE_OFFSET = 2;
	private byte[] storeByteArray = new byte[SIZE];

	public void putMyItem(int index, MyItem item) {
		storeByteArray[index * 3 + TYPE_OFFSET] = item.getType();
		storeByteArray[index * 3 + COLOR_OFFSET] = item.getColor();
		storeByteArray[index * 3 + PRICE_OFFSET] = item.getPrice();
	}

	public MyItem getMyItem(int index) {
		MyItem myItem = new MyItem();
		myItem.setType(storeByteArray[index * 3 + TYPE_OFFSET]);
		myItem.setColor(storeByteArray[index * 3 + COLOR_OFFSET]);
		myItem.setPrice(storeByteArray[index * 3 + PRICE_OFFSET]);
		return myItem;
	}
}

class ByteStore2 {
	private static final int SIZE = 1000;
	private static final int TYPE_OFFSET = 0;
	private static final int COLOR_OFFSET = 8;
	private static final int PRICE_OFFSET = 16;
	private int[] storeIntArray = new int[SIZE];

	public void putMyItem(int index, MyItem item) {
		storeIntArray[index] = 0;
		storeIntArray[index] = storeIntArray[index] | (item.getType());
		storeIntArray[index] = storeIntArray[index] | (item.getColor() << COLOR_OFFSET);
		storeIntArray[index] = storeIntArray[index] | (item.getPrice() << PRICE_OFFSET);
	}

	public MyItem getMyItem(int index) {
		MyItem myItem = new MyItem();
		myItem.setType((byte)(storeIntArray[index] & 0xFF));
		myItem.setColor((byte)(storeIntArray[index] >> COLOR_OFFSET & 0xFF));
		myItem.setPrice((byte)(storeIntArray[index] >> PRICE_OFFSET & 0xFF));
		return myItem;
	}
}